home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / DETH_SRC.ZIP / TIMERX.C < prev    next >
C/C++ Source or Header  |  1993-06-24  |  11KB  |  583 lines

  1.  
  2. /* Copyright 1993 by Peter Sprenger   Pete@amber.dinoco.de
  3.  *                   5014 Kerpen 3
  4.  *                   Germany
  5.  *
  6.  * Permission to use, copy, modify, and distribute this
  7.  * software and its documentation for any purpose and without
  8.  * fee is hereby granted, provided that the above copyright
  9.  * notice appear in all copies.  The author Peter Sprenger
  10.  * makes no representations about the suitability of this
  11.  * software for any purpose.  It is provided "as is" without
  12.  * express or implied warranty.
  13.  */
  14.  
  15.  
  16. #include <stddef.h>
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <dos.h>
  20. #include "timerx.h"
  21.  
  22. #define CINTNO 0
  23. #define SLAVEPIC 2
  24. #define RTCINTNO 8
  25.  
  26. typedef unsigned char BYTE;
  27. typedef unsigned int  WORD;
  28.  
  29. static void far interrupt (*orgtick)();
  30. static void far interrupt (*orgrtc)();
  31. static void far (*call_func)();
  32. static void far (*rtc_func)();
  33. static WORD timer_val,timer_hold,timer_diff,mue999;
  34. static WORD timadd,timsum;
  35.  
  36. /* Joystick routines are following */
  37.  
  38. WORD tax,tay,tbx,tby; /* values of potentiometer */
  39. WORD ba1,ba2,bb1,bb2; /* button values; bit set = pressed */
  40.  
  41.  
  42. /* ReadTJoy reads the potentiometer values from the joysticks */
  43. /* the argument which defines which of the 4 potis to read    */
  44. /* the 1st 4 bits correspond to the potis to read if bit set  */
  45. /* a value of 0 in tax,..tby means no joystick connected      */
  46.  
  47. void ReadTJoy(BYTE which)
  48. {
  49.     asm mov tax,0;  /* init values */
  50.     asm mov tay,0;
  51.     asm mov tbx,0;
  52.     asm mov tby,0;
  53.  
  54.     asm mov dx,0x201; /* joyport address */
  55.     asm out dx,al;
  56.  
  57.     asm mov al,0x80;  /* latch timer 2 */
  58.     asm out 0x43,al;  /* save value in bx */
  59.     asm in al,0x42;
  60.     asm mov bl,al;
  61.     asm in al,0x42;
  62.     asm mov bh,al;
  63.  
  64. joyloop:
  65.     asm in al,dx;
  66.     asm mov cl,al;    /* read joyport bits to cl */
  67.  
  68.     asm test cl,0x1;  /* timer bit set? */
  69.     asm jnz notax;
  70.     asm test tax,0xffff; /* value already got? */
  71.     asm jz getax;
  72. notax:
  73.     asm test cl,0x2;
  74.     asm jnz notay;
  75.     asm test tay,0xffff;
  76.     asm jz getay;
  77. notay:
  78.     asm test cl,0x4;
  79.     asm jnz notbx;
  80.     asm test tbx,0xffff;
  81.     asm jz getbx;
  82. notbx:
  83.     asm test cl,0x8;
  84.     asm jnz notby;
  85.     asm test tby,0xffff;
  86.     asm jz getby;
  87. notby:
  88.  
  89.     asm test cl,which;
  90.     asm jz end;
  91.  
  92.     asm mov al,0x80;
  93.     asm out 0x43,al;
  94.     asm in al,0x42;
  95.     asm mov ah,al;
  96.     asm in al,0x42;
  97.     asm xchg ah,al;
  98.     asm sub ax,bx;
  99.     asm neg ax;
  100.     asm cmp ax,5000;  /* leave routine after 5000 CLK */
  101.     asm jg end;
  102.     asm jmp joyloop;
  103.  
  104. getax:
  105.     asm mov al,0x80;
  106.     asm out 0x43,al;
  107.     asm in al,0x42;
  108.     asm mov ah,al;
  109.     asm in al,0x42;
  110.     asm xchg ah,al;
  111.     asm sub ax,bx;
  112.     asm neg ax;
  113.     asm mov tax,ax;
  114.     asm jmp joyloop;
  115.  
  116. getay:
  117.     asm mov al,0x80;
  118.     asm out 0x43,al;
  119.     asm in al,0x42;
  120.     asm mov ah,al;
  121.     asm in al,0x42;
  122.     asm xchg ah,al;
  123.     asm sub ax,bx;
  124.     asm neg ax;
  125.     asm mov tay,ax;
  126.     asm jmp joyloop;
  127.  
  128. getbx:
  129.     asm mov al,0x80;
  130.     asm out 0x43,al;
  131.     asm in al,0x42;
  132.     asm mov ah,al;
  133.     asm in al,0x42;
  134.     asm xchg ah,al;
  135.     asm sub ax,bx;
  136.     asm neg ax;
  137.     asm mov tbx,ax;
  138.     asm jmp joyloop;
  139.  
  140. getby:
  141.     asm mov al,0x80;
  142.     asm out 0x43,al;
  143.     asm in al,0x42;
  144.     asm mov ah,al;
  145.     asm in al,0x42;
  146.     asm xchg ah,al;
  147.     asm sub ax,bx;
  148.     asm neg ax;
  149.     asm mov tby,ax;
  150.     asm jmp joyloop;
  151.  
  152.  
  153. end:
  154. }
  155.  
  156. void ReadBJoy()
  157. {
  158.     asm mov dx,0x201;
  159.     asm in al,dx;
  160.     asm neg al;
  161.     asm mov bh,0;
  162.  
  163.     asm mov bl,al;
  164.     asm and bx,0x10;
  165.     asm mov ba1,bx;
  166.  
  167.     asm mov bl,al;
  168.     asm and bx,0x20;
  169.     asm mov ba2,bx;
  170.  
  171.     asm mov bl,al;
  172.     asm and bx,0x40;
  173.     asm mov bb1,bx;
  174.  
  175.     asm mov bl,al;
  176.     asm and bx,0x80;
  177.     asm mov bb2,bx;
  178. }
  179.  
  180. /* same as ReadTJoy, but uses no timer */
  181. /* a little bit inaccurate and machine dependant */
  182.  
  183. void ReadTJoy2(BYTE which)
  184. {
  185.     asm mov tax,0;  /* init values */
  186.     asm mov tay,0;
  187.     asm mov tbx,0;
  188.     asm mov tby,0;
  189.  
  190.     asm mov dx,0x201; /* joyport address */
  191.     asm out dx,al;
  192.  
  193.     asm mov cx,0;
  194.  
  195. joyloop:
  196.     asm in al,dx;
  197.  
  198.     asm test al,0x1;     /* timer bit set? */
  199.     asm jnz notax;
  200.     asm test tax,0xffff; /* value already got? */
  201.     asm jnz notax2;
  202.     asm jmp getax;
  203. notax:
  204.     asm nop
  205.     asm nop
  206.     asm nop
  207. notax2:
  208.     asm test al,0x2;
  209.     asm jnz notay;
  210.     asm test tay,0xffff;
  211.     asm jnz notay2;
  212.     asm jmp getay;
  213. notay:
  214.     asm nop
  215.     asm nop
  216.     asm nop
  217. notay2:
  218.     asm test al,0x4;
  219.     asm jnz notbx;
  220.     asm test tbx,0xffff;
  221.     asm jnz notbx2;
  222.     asm jmp getbx;
  223. notbx:
  224.     asm nop
  225.     asm nop
  226.     asm nop
  227. notbx2:
  228.     asm test al,0x8;
  229.     asm jnz notby;
  230.     asm test tby,0xffff;
  231.     asm jnz notby2;
  232.     asm jmp getby;
  233. notby:
  234.     asm nop
  235.     asm nop
  236.     asm nop
  237. notby2:
  238.  
  239.     asm test al,which;
  240.     asm jz end;
  241.  
  242.     asm inc cx;
  243.     asm cmp cx,5000;  /* leave routine after 5000 inc cx */
  244.     asm jg end;
  245.     asm jmp joyloop;
  246.  
  247. getax:
  248.     asm mov tax,cx;
  249.     asm jmp joyloop;
  250.  
  251. getay:
  252.     asm mov tay,cx;
  253.     asm jmp joyloop;
  254.  
  255. getbx:
  256.     asm mov tbx,cx;
  257.     asm jmp joyloop;
  258.  
  259. getby:
  260.     asm mov tby,cx;
  261.     asm jmp joyloop;
  262.  
  263.  
  264. end:
  265. }
  266.  
  267. /* --------------------------------------------------- */
  268.  
  269. /* timerX routines are following */
  270.  
  271. void InitT2()
  272. {
  273.     asm in al,0x61   /* no signal on speaker! */
  274.     asm and al,0xfd
  275.     asm or  al,1
  276.     asm out 0x61,al
  277.  
  278.     asm mov al,0xb4  /* program timer 2 with modus 2 */
  279.     asm out 0x43,al  /* and counter value of 0 (2^16)*/
  280.     asm mov al,0
  281.     asm out 0x42,al
  282.     asm out 0x42,al
  283. }
  284.  
  285. void timer_on()
  286. {
  287.     asm mov al,0x80;  /* latch timer 2 */
  288.     asm out 0x43,al;  /* save value in timer_hold */
  289.     asm in al,0x42;
  290.     asm mov bl,al;
  291.     asm in al,0x42;
  292.     asm mov bh,al;
  293.     asm mov timer_hold,bx;
  294. }
  295.  
  296. WORD timer_off()
  297. {
  298.     asm mov al,0x80; /* latch timer 2 */
  299.     asm out 0x43,al;
  300.     asm in al,0x42;
  301.     asm mov ah,al;
  302.     asm in al,0x42;
  303.     asm xchg ah,al;
  304.     asm mov bx,timer_hold;
  305.     asm sub ax,bx;
  306.     asm neg ax;
  307.     asm mov timer_diff,ax; /* calc timer_hold - ax to timer_diff */
  308.     return(_AX);
  309. }
  310.  
  311. WORD to_micro(WORD clk)
  312. {
  313.     return(clk*838/1000);    
  314. }
  315.  
  316. void clkdelay(WORD clicks)
  317. {
  318.     asm mov al,0x80;  /* latch timer 2 */
  319.     asm out 0x43,al;  /* save value in bx */
  320.     asm in al,0x42;
  321.     asm mov bl,al;
  322.     asm in al,0x42;
  323.     asm mov bh,al;
  324. loop:
  325.     asm mov al,0x80;
  326.     asm out 0x43,al;
  327.     asm in al,0x42;
  328.     asm mov ah,al;
  329.     asm in al,0x42;
  330.     asm xchg ah,al;
  331.     asm sub ax,bx;
  332.     asm neg ax;
  333.     asm cmp ax,clicks;  /* leave routine after click CLK's */
  334.     asm jle loop;
  335. }
  336.  
  337. void measure()
  338. {
  339.     timer_on();
  340.  
  341.     asm cli
  342.     asm mov cx,10000  /* internal test loop */
  343. loop1:
  344.     asm loop loop1
  345.  
  346.     timer_off();
  347.     asm sti
  348.     timer_val=timer_diff;
  349.  
  350.     mue999=mcalc(999); /* calc for msdelay */
  351. }
  352.  
  353. void mdelay(WORD delay)
  354. {
  355.     asm mov cx,delay
  356.  loop1:
  357.     asm loop loop1
  358. }
  359.  
  360. void msdelay(WORD delay)
  361. {
  362.     WORD i;
  363.  
  364.     for(i=0;i<delay;i++) mdelay(mue999); /* only 999 cause of fnctn call */
  365. }
  366.  
  367. WORD mcalc(WORD micro)
  368. {
  369.     return((long)micro*10000L/timer_val*1000/838);
  370. }
  371.  
  372. WORD vbl_measure()
  373. {
  374.     asm mov dx,0x3da
  375.  
  376. loop1:
  377.     asm in al,dx;  /* wait for end vbl */
  378.     asm test al,8;
  379.     asm jnz loop1;
  380.  
  381. loop2:             /* wait for vbl */
  382.     asm in al,dx;
  383.     asm test al,8;
  384.     asm jz loop2;
  385.  
  386.     asm cli
  387.     timer_on();
  388.  
  389. loop3:
  390.     asm in al,dx;  /* wait for end vbl */
  391.     asm test al,8;
  392.     asm jnz loop3;
  393.  
  394. loop4:             /* wait for vbl */
  395.     asm in al,dx;
  396.     asm test al,8;
  397.     asm jz loop4;
  398.  
  399.     timer_off();
  400.     asm sti
  401.     return(timer_diff);
  402. }
  403.  
  404. /* --------------- timer 0 stuff ----------------- */
  405.  
  406. static void interrupt timerint()
  407. {
  408.     call_func();
  409.  
  410.     if(timsum<100)
  411.     {
  412.         timsum+=timadd;
  413.         orgtick();
  414.     }
  415.     else
  416.     {
  417.         asm mov al,0x20;
  418.         asm out 0x20,al;
  419.     }
  420.     timsum-=100;
  421. }
  422.  
  423. void Install_Timer0(WORD period,void far (*func)())
  424. {
  425.     if(period<120) return;  /* timer calc's will fail */
  426.     if(!func) return;       /* no valid func ptr */
  427.     call_func=func;
  428.     timadd= (WORD)(6553600L/period);
  429.     timsum=0;
  430.  
  431.     asm mov al,0x36  /* program timer 0 with modus 3 */
  432.     asm out 0x43,al  /* and counter value of period  */
  433.     asm mov ax,period
  434.     asm out 0x40,al
  435.     asm mov al,ah
  436.     asm out 0x40,al
  437.  
  438.     enable_int(CINTNO); /* just in case... */
  439.  
  440.     orgtick= getvect(int2vect(CINTNO));   // Install 18.2 Hertz Interrupt
  441.     setvect(int2vect(CINTNO),timerint);
  442. }
  443.  
  444. void Remove_Timer0()
  445. {
  446.     asm mov al,0x36  /* program timer 0 with modus 3 */
  447.     asm out 0x43,al  /* and counter value of 0 (2^16)*/
  448.     asm mov al,0
  449.     asm out 0x40,al
  450.     asm out 0x40,al
  451.     setvect(int2vect(CINTNO),orgtick);
  452. }
  453.  
  454. /* --------------- Real Time Clock intr -----------*/
  455.  
  456. static void interrupt rtc_int()
  457. {
  458.     asm cli
  459.  
  460.     asm mov al,0x20
  461.     asm out 0xa0,al
  462.     asm out 0x20,al     /* send EOI to both intr controllers */
  463.  
  464.     asm sti
  465.  
  466.     asm mov al,0xc
  467.     asm out 0x70,al
  468.     asm in  al,0x71    /* read register c of rtc, to determine intr source & acknoledge intr */
  469.  
  470.     if(_AL & 0x40)  /* periodical rtc interrupt ? */
  471.     {
  472.         rtc_func();
  473.     }
  474. }
  475.  
  476. void Install_RTC(WORD hertz,void far (*func)())
  477. {
  478.     WORD calc;
  479.     BYTE cnt;
  480.  
  481.     if(hertz>8192) return;  /* rtc will only allow up to 8192hz */
  482.     if(!func) return;       /* no valid func ptr */
  483.     rtc_func=func;
  484.  
  485.     calc=(long)65536L/hertz;
  486.     cnt=0;
  487.     while(calc>>=1) cnt++;
  488.  
  489.     orgrtc= getvect(int2vect(RTCINTNO));
  490.     setvect(int2vect(RTCINTNO),rtc_int);
  491.  
  492.  
  493.     asm cli
  494.     enable_int(SLAVEPIC);
  495.     enable_int(RTCINTNO);
  496.  
  497.     asm mov al,0xa
  498.     asm out 0x70,al
  499.     asm in al,0x71
  500.     asm and al,0xf0
  501.     asm or  al,cnt
  502.     asm out 0x71,al
  503.  
  504.     asm mov al,0xc
  505.     asm out 0x70,al
  506.     asm mov al,0x0
  507.     asm out 0x71,al
  508.  
  509.     asm mov al,0xb
  510.     asm out 0x70,al
  511.     asm in al,0x71
  512.     asm or  al,0x40
  513.     asm out 0x71,al
  514.     asm sti
  515. }
  516.  
  517. void Remove_RTC()
  518. {
  519.     asm cli
  520.     setvect(int2vect(RTCINTNO),orgrtc);
  521.     asm mov al,0xb         /* remove setting of periodical intr */
  522.     asm out 0x70,al
  523.     asm in al,0x71
  524.     asm and  al,0x0f
  525.     asm out 0x71,al
  526.     asm sti
  527.     /* do not disable in intr controller because their could be a bios routine */
  528. }
  529.  
  530. BYTE int2vect(BYTE intnr)
  531. {
  532.     if(intnr>7) return(intnr+0x68);
  533.     else return(intnr+8);
  534. }
  535.  
  536. void enable_int(BYTE nr)
  537. {
  538.     if(nr>7) /* use 2nd intr controller? */
  539.     {
  540.         asm in al,0xa1;
  541.         asm mov cl,nr;
  542.         asm sub cl,8
  543.         asm mov bl,1;
  544.         asm shl bl,cl;  /* calc correct mask */
  545.         asm not bl;
  546.         asm and al,bl;
  547.         asm out 0xa1,al;
  548.     }
  549.     else
  550.     {
  551.         asm in al,0x21;
  552.         asm mov cl,nr;
  553.         asm mov bl,1;
  554.         asm shl bl,cl; /* calc correct mask */
  555.         asm not bl;
  556.         asm and al,bl;
  557.         asm out 0x21,al;
  558.     }
  559. }
  560.  
  561. void disable_int(BYTE nr)
  562. {
  563.     if(nr>7)
  564.     {
  565.         asm in al,0xa1;      /* use 2nd intr controller? */
  566.         asm mov cl,nr;
  567.         asm sub cl,8
  568.         asm mov bl,1;
  569.         asm shl bl,cl;    /* calc correct mask */
  570.         asm or al,bl;
  571.         asm out 0xa1,al;
  572.     }
  573.     else
  574.     {
  575.         asm in al,0x21;
  576.         asm mov cl,nr;
  577.         asm mov bl,1;
  578.         asm shl bl,cl;    /* calc correct mask */
  579.         asm or al,bl;
  580.         asm out 0x21,al;
  581.     }
  582. }
  583.